;------------------------------------------------------------------------------
;
; As yet untitled
; The Calodox ZX81 Intro
; Copyright (c) 2003 Sebastian Gerlach
;
; ZX81 speedloader
;
; This program is the loader for the intro. It has the following features:
; - Faster loading, about 12 times faster than usual.
; - Resides in the system variable area, is smaller than the usual system
;   variables. So it does not waste any memory.
; - Does not require the usual basic header on loaded files.
; 
; In its current state, it takes 52 bytes. It could actually load quite a
; bit faster, but I am afraid that it will cease working with usual audio
; equipment in that case. Currently output is provided by a PC sound card 
; at 22kHz sampling rate. The shortest elements are one sample long.
;
;------------------------------------------------------------------------------

.z80            ;use Z80 instruction set

org 4009h
	db 0,0,0
	dw displayfile, displayfile	
	
	dw varfile
	dw 0
	dw varfile+1
	dw 0
	dw 0
	dw varfile+3,varfile+3
	db 0ffh, 5dh
		
	dw 40h, 2
	db 0
	dw 0ffffh
	db 0, 37h
	dw 403ch,0,0
	db 0
	
	dw 0,0,0ffffh, 0, 213ch, 4000h
	
	; The fancy BASIC line to get us going
	db 000h, 001h, 00ah, 000h
	db 0f0h, 0d4h, 020h, 07eh, 08fh, 000h, 094h, 000h, 000h, 076h

start_here:
	call 0f23h						; Set fast mode
	
	; Copy loader to start of RAM
	ld de, 4000h					; Start of RAM
	ld hl, loaderpos				; Start of loader
	ld bc, memend-loaderstart		; Length of loader
	ldir							; Copy loader
	
	; Jump to copy of loader
	jr 4000h
	
loaderpos:

;org 4000h
	
loaderstart:
	out (0fdh), a					; Disable NMI
	ld hl, memend-loaderstart+4000h	; Load start address
	
	; Wait for high state on tape
startbyte:
    in a, (0feh)					; Read tape bit
    out (0ffh), a					; Display fancy pattern
    rla								; Shift bit into carry
    jr nc,startbyte					; Wait for bit to be one
    
    ; Read in the bits
    ld b, 8							; 8 bits per byte
    ld c, 0							; Current value of byte
nextbit:
	ld e,0							; Delay counter

	; Wait for end of high state
waitbitend:
    in a, (0feh)					; Read tape bit
    rla								; Shift bit into carry
	jr c, waitbitend				; Wait for bit to be zero
	
	; Wait for start of high state
waitbit:
    in a, (0feh)					; Read tape bit
    inc e							; Count number of iterations
    rla								; Shift tape bit into carry
	jr nc, waitbit					; Wait for bit to be one
	
	ccf								; Set carry flag to zero
	bit 4,e							; Check bit 4 of iteration counter
	jr z, zbit						; If zero, this bit is a zero
	scf								; If non-zero, this bit is a one
zbit:
	rl c							; Shift carry into c
	djnz nextbit					; Read next bit
	bit 5,e							; Overlong zero to mark end of file
	jr nz, loaderend
	
	; Wait for end of high state
waitbitend2:
    in a, (0feh)					; Read tape bit
    rla								; Shift tape bit into carry
	jr c, waitbitend2				; Wait for bit to be zero
	
	ld (hl), c						; Load byte into memory
    inc hl							; Increment memory counter
    
    jr startbyte					; Continue loading
    
loaderend:
memend:		
displayfile:
	db 76h,76h,76h,76h,76h,76h,76h,76h
	db 76h,76h,76h,76h,76h,76h,76h,76h
	db 76h,76h,76h,76h,76h,76h,76h,76h,76h
varfile:	
	db 80h

end start_here
